package com.service.business.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.member.dto.MemberStoreChange;
import com.service.business.member.service.MemberStoreService;
import com.service.business.merchant.controller.rep.CreditLineStatementPageRep;
import com.service.business.merchant.controller.rep.MemberCreditLineRep;
import com.service.business.merchant.service.MerchantCreditLineService;
import com.service.business.merchant.service.MerchantCreditLineStatementService;
import com.service.business.merchant.service.MerchantService;
import com.service.business.support.Language;
import com.service.business.support.SessionUtil;
import com.service.business.utils.I18nUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.request.PageRequest;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.dto.MerchantCreditLineChange;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.MemberJAType;
import com.service.dao.enums.StatementTypeEnum;
import com.service.dao.mapper.MerchantCreditLineMapper;
import com.service.dao.model.MemberStore;
import com.service.dao.model.Merchant;
import com.service.dao.model.MerchantCreditLine;
import com.service.dao.model.MerchantCreditLineStatement;
import com.service.utility.common.MathUtil;
import com.service.utility.modelmapper.ModelMapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;


@Service("merchantCreditLineService")
public class MerchantCreditLineServiceImpl extends ServiceImpl<MerchantCreditLineMapper, MerchantCreditLine> implements MerchantCreditLineService {

    @Autowired
    private SessionUtil sessionUtil;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private MemberStoreService memberStoreService;
    @Autowired
    private MerchantCreditLineStatementService statementService;

    @Override
    public MemberCreditLineRep merchantCreditLine() {
        LoginUserSession session = sessionUtil.getUser();
        MerchantCreditLine merchantCreditLine = getOne(new QueryWrapper<MerchantCreditLine>()
                .lambda().eq(MerchantCreditLine::getMemberId, session.getUserId()));

        if (ObjectUtils.isEmpty(merchantCreditLine)) {
            throw new CommonException("暂无授信额度", "merchant_credit_line_exception_empty");
        }
        return ModelMapperUtil.map(merchantCreditLine, MemberCreditLineRep.class);
    }

    @Override
    public CommonPageRep<CreditLineStatementPageRep> pageStatement(CoinsEnum coins, PageRequest pageRequest) {
        LoginUserSession session = sessionUtil.getUser();
        MerchantCreditLine merchantCreditLine = getOne(new QueryWrapper<MerchantCreditLine>()
                .lambda().eq(MerchantCreditLine::getMemberId, session.getUserId()));

        if (ObjectUtils.isEmpty(merchantCreditLine)) {
            throw new CommonException("暂无授信额度", "merchant_credit_line_exception_empty");
        }

        return statementService.pageStatement(coins, merchantCreditLine.getId(), pageRequest);
    }

    @Override
    public void updateCreditLineBalance(MerchantCreditLineChange creditLineChange) {
        updateCreditLineBalance(getCreditLine(creditLineChange.getMerchantId(), creditLineChange.getCoinsName()), creditLineChange);
    }

    public void updateCreditLineBalance(MerchantCreditLine creditLine, MerchantCreditLineChange creditLineChange) {

        creditLineChange.getStatementType().doOptStore(creditLine, creditLineChange.getChangeNum());
        BigDecimal residueNum = creditLine.getResidueNum();

        MerchantCreditLineStatement statement = MerchantCreditLineStatement.builder()
                .changeNum(creditLineChange.getChangeNum())
                .coinsId(creditLineChange.getCoinsId())
                .coinsName(creditLineChange.getCoinsName())
                .merchantId(creditLine.getMerchantId())
                .creditLineId(creditLine.getId())
                .orderId(creditLineChange.getOrderId())
                .remark(creditLineChange.getRemark())
                .residueNum(residueNum)
                .creditNum(creditLine.getCreditNum())
                .statementType(creditLineChange.getStatementType().getCode())
                .createTime(new Date())
                .build();

        statementService.save(statement);

        updateById(MerchantCreditLine.builder().creditNum(creditLine.getCreditNum())
                .residueNum(creditLine.getResidueNum()).id(creditLine.getId()).build());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MerchantCreditLine getCreditLine(Integer merchantId, String coinsName) {
        CoinsEnum coinsEnum = CoinsEnum.valueOf(coinsName);
        return getCreditLine(merchantId, coinsEnum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MerchantCreditLine getCreditLine(Integer merchantId, CoinsEnum coins) {
        MerchantCreditLine result = getOne(new QueryWrapper<MerchantCreditLine>().lambda()
                .eq(MerchantCreditLine::getMerchantId, merchantId)
                .eq(MerchantCreditLine::getCoinsName, coins.getName()));

        if (ObjectUtils.isEmpty(result)) {

            Merchant merchant = merchantService.getById(merchantId);

            if (ObjectUtils.isEmpty(merchant)) {
                throw new CommonException("该商家不存在", "merchant_exception_not_exit");
            }
            result = MerchantCreditLine.builder()
                    .merchantId(merchantId)
                    .memberId(merchant.getMemberId())
                    .coinsId(coins.getCode())
                    .coinsName(coins.getName())
                    .creditNum(BigDecimal.ZERO)
                    .residueNum(BigDecimal.ZERO)
                    .createTime(new Date())
                    .build();

            save(result);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void repayment(MerchantCreditLine creditLine, MemberStore memberStore, BigDecimal repaymentNum) {

        if(memberStore.getNum().compareTo(repaymentNum) < 0){
            repaymentNum = memberStore.getNum();
        }



        MemberStoreChange storeChange = MemberStoreChange.builder()
                .memberId(memberStore.getMemberId())
                .coinsId(memberStore.getCoinsId())
                .coinsName(memberStore.getCoinsName())
                .changeNum(repaymentNum)
                .jaType(MemberJAType.REPAYMENT)
                .remark("还款:"+creditLine.getMerchantId())
                .build();

        Integer jaId = memberStoreService.changeMemberStore(storeChange);

        MerchantCreditLineChange creditLineChange = MerchantCreditLineChange.builder()
                .coinsId(creditLine.getCoinsId())
                .coinsName(creditLine.getCoinsName())
                .changeNum(repaymentNum)
                .statementType(StatementTypeEnum.REPAYMENT)
                .remark("还款(会员账户流水:"+jaId+")")
                .build();

        updateCreditLineBalance(creditLine, creditLineChange);

    }
}
